import pandas as pd
import numpy as np
from tqdm import tqdm
import FindException
import Draw
import pylab as plt

# 基本的数据预处理
def drop_duplicates(data: pd.DataFrame):
    """
    1、删除矩阵DataFrame的第二项起重复值，并将其返回
    2、一般情况下删除整行都是重复的这种
    3、如果有特殊需求，请在drop_duplicates的参数里面可以填根据的列来删除重复项
    :param data: 输入的矩阵数据
    :return: 删除的重复项
    """
    # 删除重复值
    print('删除重复值......')
    droped_data = data.drop_duplicates(inplace=True)
    return droped_data


def Duplicated_Exception(data: pd.DataFrame):
    """
    1、对于矩阵DataFrame的异常值将其替换为缺失值
    2、默认使用ffill向下填充异常值,ffill未填充到的部分，采用平均值来填充
    3、可以考虑使用差值等其他方法填充
    :param data:数据矩阵
    :return:
    data:处理后的数据
    Exception_series:每一列的错误数量
    Exception_Percentage:每一列的错误数量占该列的百分比
    Exceptions:每一列的异常值，形成的列表,该列表可能是长短不一的
    """
    # 寻找异常值
    print('处理异常值和缺失值......')
    # 初始化每个指标的异常值数量
    Nums = [0] * len(data.columns)
    # 初始化每列的异常值列表
    Exceptions=[]
    for i in tqdm(range(data.shape[1])):
        # 获取每列的错误bool判断值
        Judge = FindException.FindException(data.iloc[:, i])
        # 记录每一列的错误个数
        Nums[i] += len(data.iloc[:, i][Judge])
        # 记录每一列的异常项目
        Exceptions.append(data.iloc[:, i][Judge])
        # 将异常值置为nan
        data.iloc[:, i][Judge] = np.nan
        # 向下填充异常值
        data.iloc[:, i].ffill(inplace=True)
        # 用平均值填充
        data.iloc[:, i][data.iloc[:, i] != data.iloc[:, i]] = data.iloc[:, i].mean()
    # 异常值数量转换为Series,便于导出结果
    Exception_series = pd.Series(Nums)
    # 异常值的占比
    Exception_Percentage = Exception_series / data.shape[0]
    return data, Exception_series, Exception_Percentage,Exceptions


# 绘制错误点
def Draw_Exception(data:pd.DataFrame):
    data.plot()
    col_Jundges=[]
    for i in tqdm(range(data.shape[1])):
        Judge = FindException.FindException(data.iloc[:, i])
        plt.plot(data.iloc[:,i][Judge],'ro')
    return col_Jundges
